﻿using System.Threading;

namespace DambachMulti.Processing
{
	/// <summary>
	/// Represents a single dedicated processor by allocating a thread of high priority to it...
	/// </summary>
	public class Core
	{
		//publics
		public	ThunkList		Thunks	= null; //a list of delegates that may be executed in any order			
		private	AutoResetEvent	Start	= new AutoResetEvent(false);		
		private AutoResetEvent	Finish	= new AutoResetEvent(false);

		//privates
		private Thread	worker	= null;		//the thread that represents a dedicated processor
		private bool	stop	= false;	//always starts out as false

		//constructor
		public Core() //initialize the thread and get it running
		{
			this.Thunks	= new ThunkList(); 
			this.Start	= new AutoResetEvent( false );
			this.Finish = new AutoResetEvent( false );			
			//done with preliminaries...

			//set up the thread that gives us access to the cpu
			this.worker					= new Thread( Work );
			this.worker.Priority		= ThreadPriority.AboveNormal; //represents a dedicated-yet still responsive processor
			this.worker.IsBackground	= true; //this means that when the process is ended, these threads will be ended too
			//the above line fixed the lingering process bug! FIXED!!!
			this.worker.Start(); //begin the work loop
		}

		public void BeginProcessing() { this.Start.Set(); }

		public void FinishProcessing() 
		{
			this.Start.Set(); //make sure it goes all the way through once more
			this.Finish.WaitOne();			
		}

		public ThreadPriority Priority
		{	//everything taken away that ought, and nothing needing to be added...This is beauty
			get { return this.worker.Priority;	}
			set { this.worker.Priority = value;	}
		}

		private void Work() //always running, sometimes blocking
		{			
			while( !this.stop ) //go forever!!! until its time to close
			{
				Start.WaitOne( 1, false ); //not really sure what the second param is, if I have any trouble, look at it first
				lock( Thunks )
				{
					foreach( Thunk<object> t in this.Thunks )					
						t.Method( t.Parameter );
					Thunks.Clear();
				}
				Finish.Set();				
			}
		}

		~Core() //cleanup threads and stuff
		{	//not sure that this is needed anymore...well its not intensive
			//and not causing any problems
			stop = true; //let the threads exit naturally			
			FinishProcessing(); //and complete any remaining work items
		}
	}
}
